
#include <Servo.h>
#include <Ticker.h>

#define PLUS D1         // +
#define SUB  D2         // -

//读按键值
#define KEYP      digitalRead(PLUS)
#define KEYS      digitalRead(SUB)

#define short_press_time 10     //短按时间
#define long_press_time 1000    //长按时间

#define NO_KEY_PRES     0   //无按键按下
 
#define PLUS_KEY_PRES     1
#define SUB_KEY_PRES      2
 
#define PLUS_KEY_LONG_PRES     11
#define SUB_KEY_LONG_PRES          22

bool KEYP_UP = 0;//按键状态，0为弹起，1为按下
bool KEYS_UP = 0;//按键状态，0为弹起，1为按下

uint16_t KEYP_PRESS_COUNT = 0;//按KEYU时间计数
uint16_t KEYS_PRESS_COUNT = 0;//按KEYM时间计数

uint8_t KEYP_KEY_READ = NO_KEY_PRES;//KEYU按键状态
uint8_t KEYS_KEY_READ = NO_KEY_PRES;//KEYM按键状态

bool PLUS_INIT = 0; //舵机角度调整，0为不工作，1为工作
bool SUB_INIT = 0;  //舵机角度调整，0为不工作，1为工作
bool ACK = 1;  //舵机角度确定，0为确定，1为不确定

Ticker key_tick;
Servo myServo;  // 定义Servo对象来控制
int pos = 90;    // 角度存储变量

void flip() {
  //PLUS_KEY
  if(KEYP==0){
    KEYP_PRESS_COUNT++;
    KEYP_UP = 1;
    if(KEYP_PRESS_COUNT<=short_press_time)
      KEYP_KEY_READ = NO_KEY_PRES;
    if(KEYP_PRESS_COUNT>=short_press_time&&KEYP_PRESS_COUNT<=long_press_time)
      KEYP_KEY_READ = PLUS_KEY_PRES;
    if(KEYP_PRESS_COUNT>=long_press_time)
      KEYP_KEY_READ = PLUS_KEY_LONG_PRES;
  }
  if(KEYP){
    KEYP_PRESS_COUNT = 0;
    KEYP_UP = 0;//按键状态，0为弹起，1为按下
  }
  //SUB_KEY
  if(KEYS==0){
    KEYS_PRESS_COUNT++;
    KEYS_UP = 1;
    if(KEYS_PRESS_COUNT<=short_press_time)
      KEYS_KEY_READ = NO_KEY_PRES;
    if(KEYS_PRESS_COUNT>=short_press_time&&KEYS_PRESS_COUNT<=long_press_time)
      KEYS_KEY_READ = SUB_KEY_PRES;
    if(KEYS_PRESS_COUNT>=long_press_time)
      KEYS_KEY_READ = SUB_KEY_LONG_PRES;
  }
  if(KEYS){
    KEYS_PRESS_COUNT = 0;
    KEYS_UP = 0;//按键状态，0为弹起，1为按下
  }


  if(KEYP_KEY_READ == PLUS_KEY_LONG_PRES && KEYP_UP == 0){
    Serial.println("--KEY_PLUS长按");
    ACK = 0; //确认舵机角度
    KEYP_KEY_READ = NO_KEY_PRES;
  }
  if(KEYP_KEY_READ == PLUS_KEY_PRES && KEYP_UP == 0){
    Serial.println("--KEY_PLUS短按");
    PLUS_INIT = 1; //舵机角度调整工作
    KEYP_KEY_READ = NO_KEY_PRES;
  }
 
  if(KEYS_KEY_READ == SUB_KEY_LONG_PRES && KEYS_UP == 0){
    Serial.println("--KEY_SUB长按");
    KEYS_KEY_READ = NO_KEY_PRES;
    ACK = 1;  //不确认舵机角度
    pos = 90;  //角度归中
    initServo();
  }
  if(KEYS_KEY_READ == SUB_KEY_PRES && KEYS_UP == 0){
    Serial.println("--KEY_SUB短按");
    SUB_INIT = 1; //舵机角度调整工作
    KEYS_KEY_READ = NO_KEY_PRES;
  }

}

void initServo(){
  Serial.println("舵机角度初始化");
  while(ACK){
    if(PLUS_INIT){
      pos += 10;
      PLUS_INIT = 0;
    }
    if(SUB_INIT){
      pos -= 10;
      SUB_INIT = 0;
    }
    myServo.write(pos);              // 舵机角度写入
    delay(100);
  }
  Serial.println("舵机角度调整结束");
  Serial.println(pos);
  myServo.write(90);              // 舵机角度写入
  delay(100);
}

void setup() {
  // Start Serial
  Serial.begin(115200);
  delay(100);

  myServo.attach(12); //D6 
  myServo.write(pos);              // 舵机角度写入
  delay(50);
  
  //prepare interupt  设置外置按钮管脚为上拉输入模式
  pinMode(PLUS,INPUT_PULLUP);
  pinMode(SUB,INPUT_PULLUP);
  pinMode(D5, OUTPUT); //设置D5引脚为输出模式以便控制LED

  key_tick.attach_ms(1, flip);//按键检测定时器（1ms）

  initServo();
}

void loop() {

}
